/**
 * 导入模块
 */
import axios from 'axios';

/**
 * 导入类型声明
 */
import type { AxiosInstance, AxiosResponse } from 'axios';
import type { InterceptorHooks, ExpandAxiosRequestConfig } from './types';

/**
 * 定义请求类
 */
class AxiosRequest {
  /**
   * axios 实例
   */
  private _instance: AxiosInstance;

  /**
   * 自定义拦截器
   */
  private _interceptorHooks?: InterceptorHooks;

  /**
   * 构造函数
   * @param config
   */
  constructor(config: ExpandAxiosRequestConfig) {
    this._instance = axios.create(config);
    this._instance.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
    this._interceptorHooks = config.interceptorHooks;
    this.setupInterceptors();
  }

  /**
   * 通用拦截，在初始化时就进行注册和运行，对基础属性进行处理
   */
  private setupInterceptors() {
    this._instance.interceptors.request.use(
      this._interceptorHooks?.requestInterceptor,
      this._interceptorHooks?.requestInterceptorCatch,
    );
    this._instance.interceptors.response.use(
      this._interceptorHooks?.responseInterceptor,
      this._interceptorHooks?.responseInterceptorCatch,
    );
  }

  /**
   * 基础get方法
   * @param url
   * @param config
   * @returns
   */
  public get<T = any>(url: string, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.get(url, config);
  }

  /**
   * 基础post方法
   * @param url
   * @param data
   * @param config
   * @returns
   */
  public post<T = any>(url: string, data?: any, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.post(url, data, config);
  }

  /**
   * 基础put方法
   * @param url
   * @param data
   * @param config
   * @returns
   */
  public put<T = any>(url: string, data?: any, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.put(url, data, config);
  }

  /**
   * 基础删除方法
   * @param url
   * @param config
   * @returns
   */
  public delete<T = any>(url: string, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.delete(url, config);
  }

  /**
   * 基础通用方法，传入config,自由配置组合
   * @param config
   * @returns
   */
  public request<T = any>(config: any): Promise<T> {
    return this._instance.request(config);
  }
}

export default AxiosRequest;
